<?php

namespace esign;

/**
 * Http 请求类
 */
class EsignHandle
{

    public static $connectTimeout = 30;//30 second
    public static $readTimeout = 80;//80 second
    public static $host = 'https://smlopenapi.esign.cn';
    // 项目Id(应用Id）
    public static $project_id = '7438920757';
    // 项目密钥(应用密钥）
    public static $project_scert = '29701b8073935df9b3c31c3766aa5ab4';

    /**
     * 
     */
    public static function sendRequest($reqType='GET', $url, $headers=array(), $param=null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $reqType);

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $postData = is_array($param) ? json_encode($param, JSON_UNESCAPED_SLASHES) : $param;
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        
        if (self::$readTimeout) {
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$readTimeout);
        }
        if (self::$connectTimeout) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
        }
        //https request
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (is_array($headers) && 0 < count($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        $curlRes = curl_exec($ch);

        curl_close($ch);

        return $curlRes;
    }

    public static function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
    }

    /**
     * 构造头部信息
     * @param $contentMD5
     * @param $reqSignature
     * @return array
     */
    public static function buildCommHeader($contentMD5,$reqSignature){
        if(empty($contentMD5)){
            $headers = array(
                'X-Tsign-Open-App-Id:'.self::$project_id,
                'X-Tsign-Open-Ca-Timestamp:'.self::getMillisecond(),
                'Accept:*/*',
                'X-Tsign-Open-Ca-Signature:'.$reqSignature,
                //'Content-MD5:'.$contentMD5,
                'Content-Type:application/json;charset=UTF-8',
                'X-Tsign-Open-Auth-Mode:Signature'
            );
        }else{
            $headers = array(
                'X-Tsign-Open-App-Id:'.self::$project_id,
                'X-Tsign-Open-Ca-Timestamp:'.self::getMillisecond(),
                'Accept:*/*',
                'X-Tsign-Open-Ca-Signature:'.$reqSignature,
                'Content-MD5:'.$contentMD5,
                'Content-Type:application/json;charset=UTF-8',
                'X-Tsign-Open-Auth-Mode:Signature'
            );
        }
        
        return $headers;
    }

    public static function getContentBase64Md5($filePath){
        //获取文件MD5的128位二进制数组
        $md5file = md5_file($filePath,true);
        //计算文件的Content-MD5
        $contentBase64Md5 = base64_encode($md5file);
        return $contentBase64Md5;
    }

    public static function getSignature($httpMethod,$accept,$contentType,$contentMd5,$date,$headers,$url){

        $stringToSign = $httpMethod . "\n" . $accept . "\n"  . $contentMd5 . "\n" . $contentType . "\n"  . $date . "\n" .$headers  ;
        if($headers != ''){
            $stringToSign .= "\n".$url;
        }else{
            $stringToSign .= $url;
        }

        $signature = hash_hmac("sha256",$stringToSign, self::$project_scert, true);
        
        $signature = base64_encode($signature);

        return $signature;
    }

    public static function getFileUploadUrl($filePath,$name){
        $contentBase64Md5 = self::getContentBase64Md5($filePath);
        $filesize = filesize($filePath);
        $fileContent = file_get_contents($filePath);

        $param = [];
        $param['contentMd5'] = $contentBase64Md5;
        $param['contentType'] = 'application/pdf';
        $param['fileName'] = $name;
        $param['fileSize'] = $filesize;
        $param['convert2Pdf'] = false;
        $paramStr=json_encode($param,JSON_UNESCAPED_SLASHES);
        $contentMd5=base64_encode(md5($paramStr,true));
        $url = self::$host.'/v1/files/getUploadUrl';

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('POST',"*/*","application/json;charset=UTF-8",$contentMd5,"","",'/v1/files/getUploadUrl');

        $headers = self::buildCommHeader($contentMd5,$reqSignature);
        //return $filesize;
        return self::sendRequest('POST',$url,$headers,$param);
    }

    /**
     * 文件上传
     * @param $uploadUrls
     * @param $filePath
     * @param $ContenType
     * @return string
     */
    public static function upLoadFileHttp($uploadUrls,$filePath,$ContenType){
        $fileContent = file_get_contents($filePath);
        $contentBase64Md5 = self::getContentBase64Md5($filePath);
        $header = array(
            'Content-Type:'.$ContenType,
            'Content-Md5:' . $contentBase64Md5
        );


        $curl_handle = curl_init();
        curl_setopt($curl_handle, CURLOPT_URL, $uploadUrls);
        curl_setopt($curl_handle, CURLOPT_FILETIME, true);
        curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false);
        curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000);
        curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false);

        curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT');

        curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $fileContent);
        if (is_array($header) && 0 < count($header)) {
            curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
        }
        $curlRes = curl_exec($curl_handle);

        return $curlRes;
    }

    public static function searchKeyWord($field,$keywords){

        $param = [];
        
        
        $paramStr=json_encode($param,JSON_UNESCAPED_SLASHES);
        $contentMd5=base64_encode(md5($paramStr,true));
        $url = self::$host.'/v1/documents/'.$field.'/searchWordsPosition?keywords='.urlencode($keywords);
        $contentMd5="";

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('GET',"*/*","application/json;charset=UTF-8",$contentMd5,"","",'/v1/documents/'.$field.'/searchWordsPosition?keywords='.$keywords);

        $headers = self::buildCommHeader($contentMd5,$reqSignature);
        //return '/v1/documents/'.$field.'/searchWordsPosition?keywords='.$keywords;

        return self::sendRequest('GET',$url,$headers);
    }

    public static function CreateAccount($phone,$name,$card_id){

        $param = [];
        $param['thirdPartyUserId'] = $card_id;
        $param['name'] = $name;
        $param['idType'] = 'CRED_PSN_CH_IDCARD';
        $param['idNumber'] = $card_id;
        $param['mobile'] = $phone;
        $param['email'] = '';
        $paramStr=json_encode($param,JSON_UNESCAPED_SLASHES);
        //var_dump($param);
        $contentMd5=base64_encode(md5($paramStr,true));
        //var_dump(md5($paramStr,true));
        $url = self::$host.'/v1/accounts/createByThirdPartyUserId';

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('POST',"*/*","application/json;charset=UTF-8",$contentMd5,"","",'/v1/accounts/createByThirdPartyUserId');

        $headers = self::buildCommHeader($contentMd5,$reqSignature);
        
        //return $filesize;
        return self::sendRequest('POST',$url,$headers,$param);
    }

    public static function CreateFlow($theme,$position,$fileid){

        $param = [];
        $flowInfo = [];
        $flowInfo['businessScene'] = $theme;
        $flowInfo['autoArchive'] = true;
        $flowInfo['autoInitiate'] = true;

        $flowConfigInfo = [];
        $flowConfigInfo['noticeType'] = '1';
        $flowInfo['flowConfigInfo'] = $flowConfigInfo;

        $param['flowInfo'] = $flowInfo;

        $signers = [];
        foreach($position as $p){
            $tmp = [];
            $signerAccount = [];
            $signerAccount['signerAccountId'] = $p['account_id'];
            $signerAccount['authorizedAccountId'] = $p['account_id'];
            $signerAccount['noticeType'] = '1';
            $tmp['signerAccount'] = $signerAccount;

            $signfields = [];
            $sf = [];
            $sf['fileId'] = $fileid;
            $posBean = [];
            $posBean['posPage'] = $p['page'];
            $posBean['posX'] = $p['posx'];
            $posBean['posY'] = $p['posy'];
            $sf['posBean'] = $posBean;
            $signfields[] = $sf;
            $tmp['signfields'] = $signfields;
            $signers[] = $tmp;
        }

        $param['signers'] = $signers;

        $docs = [];
        $d = [];
        $d['fileId'] = $fileid;
        $d['fileName'] = $theme;
        $docs[] = $d;
        $param['docs'] = $docs;

        
        $paramStr=json_encode($param,JSON_UNESCAPED_SLASHES);
        
        $contentMd5=base64_encode(md5($paramStr,true));
        $url = self::$host.'/api/v2/signflows/createFlowOneStep';

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('POST',"*/*","application/json;charset=UTF-8",$contentMd5,"","",'/api/v2/signflows/createFlowOneStep');

        $headers = self::buildCommHeader($contentMd5,$reqSignature);

        //return $filesize;
        return self::sendRequest('POST',$url,$headers,$param);
    }

    public static function getExecuteUrl($flowid,$accountId,$type){

        $param = [];
        
        
        $paramStr=json_encode($param,JSON_UNESCAPED_SLASHES);
        $contentMd5=base64_encode(md5($paramStr,true));
        $url = self::$host.'/v1/signflows/'.$flowid.'/executeUrl?accountId='.$accountId.'&urlType='.$type;
        $contentMd5="";

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('GET',"*/*","application/json;charset=UTF-8",$contentMd5,""
                            ,"",'/v1/signflows/'.$flowid.'/executeUrl?accountId='.$accountId.'&urlType='.$type);

        $headers = self::buildCommHeader($contentMd5,$reqSignature);
        //return '/v1/documents/'.$field.'/searchWordsPosition?keywords='.$keywords;

        return self::sendRequest('GET',$url,$headers);
    }

    public static function deleteAccount($card_id){

        $url = self::$host.'/v1/accounts/deleteByThirdId?thirdPartyUserId='.$card_id;
        $contentMd5="";

		//传入生成的bodyMd5,加上其他请求头部信息拼接成字符串,整体做sha256签名
        $reqSignature = self::getSignature('DELETE',"*/*","application/json;charset=UTF-8",$contentMd5,"","",'/v1/accounts/deleteByThirdId?thirdPartyUserId='.$card_id);

        $headers = self::buildCommHeader($contentMd5,$reqSignature);
        //return '/v1/documents/'.$field.'/searchWordsPosition?keywords='.$keywords;

        return self::sendRequest('DELETE',$url,$headers);
    }
    
}
